package it.unicam.cs.cosy.bioshape.core.components;

import it.unicam.cs.cosy.bioshape.core.components.services.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;

import javax.vecmath.Tuple3d;

/**
 * Represents a request issued from the {@code ShapedEntity} to the services
 * available in the environment. The requests contains a {@code HashMap} which
 * has pairs {@code String} - {@code Object}. The {@code String} represents the
 * name of the {@code Service} which the {@code LocalCoordinator} must query for
 * the {@code Entity}, the value is set in the {@code Object} value field. Note
 * that the class requires that the passed keys are {@code Class} objects but
 * the key are actually {@code String} objects obtained through the
 * {@code Class#getSimpleName()} method.
 * 
 * @author Federico Buti
 * 
 * @see Class#getSimpleName()
 * @see LocalCoordinator
 * @see ShapedEntity
 */
public class ShapeRequest implements Serializable {

	/** Auto-generated serial ID */
	private static final long serialVersionUID = 6722222823135183266L;

	private double radius;
	private Tuple3d center;
	private HashMap<Pair<String, String>, ArrayList<?>> map;

	/**
	 * Builds the request object given the radius, the current center and the
	 * map of services requests.
	 * 
	 * @param radius
	 *            used mainly in the perception of the environment.
	 * @param center
	 *            current position of the entity.
	 * @param map
	 *            name-value map of the services to query.
	 */
	public ShapeRequest(double radius, Tuple3d center,
			HashMap<Pair<String, String>, ArrayList<?>> map) {
		this.radius = radius;
		this.center = center;
		if (map != null)
			this.map = map;
		else
			this.map = new HashMap<Pair<String, String>, ArrayList<?>>();
	}

	void reset() {
		map.entrySet().clear(); // TODO verificare!
	}

	void setRadius(double radius) {
		this.radius = radius;
	}

	double getRadius() {
		return radius;
	}

	Tuple3d getCenter() {
		return center;
	}

	void setCenter(Tuple3d v) {
		center.set(v);
	}

	void addServiceEntry(Class<? extends Service> entry, String operation) {
		if (!map.containsKey(entry))
			map.put(new Pair<String, String>(entry.getSimpleName(), operation),
					null);
	}

	void addServiceEntry(Class<? extends Service> entry, String operation,
			ArrayList<?> array) {
		if (!map.containsKey(entry))
			map.put(new Pair<String, String>(entry.getSimpleName(), operation),
					array);
	}

	ArrayList<?> getServiceData(Class<? extends Service> entry, String operation) {
		return getServiceData(entry.getSimpleName(), operation);
	}

	ArrayList<?> getServiceData(String entry, String operation) {
		for (Pair<String, String> key : map.keySet())
			if (key.e1.equals(entry) && key.e2.equals(operation))
				return map.get(key);
		return null;
	}
}